import API from "./services";
import type { TYPE } from "../types";
import { useState, useEffect } from "react";
import { Tag, Drawer, Form, Input, Tree, Button, Space, Spin } from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { useAccess, Access } from "@umijs/max";

export default () => {
  const [data, dataSet] = useState<TYPE.RoleItem[]>([]);
  const [loading, loadingSet] = useState(false);
  const [saveLoading, saveLoadingSet] = useState(false);
  const [visible, visibleSet] = useState(false);
  const [action, actionSet] = useState<"Add" | "Edit">("Add");
  const [editId, editIdSet] = useState(0);
  const [treeData, treeDataSet] = useState<TYPE.TreeItem[]>([]);
  const [menuIds, menuIdSet] = useState("");
  const [checkedKeys, checkedKeysSet] = useState<{
    checked: number[], halfChecked: number[],
  }>({ checked: [], halfChecked: [] });

  const [formRef] = Form.useForm();
  const ac = useAccess();

  const getData = () => {
    loadingSet(true);
    API.role().then(({ data, treeData, menuIds }) => {
      loadingSet(false);
      dataSet(data);
      treeDataSet(treeData);
      menuIdSet(menuIds);
    }).catch(() => loadingSet(false));
  };

  useEffect(getData, []);

  useEffect(() => saveLoadingSet(false), [visible]);

  const save = () => {
    formRef.validateFields().then((formData: any) => {
      // 从"可用功能"数据中，分离出菜单数据和资源数据。
      const menu: number[] = [], res: number[] = [];
      const { checked, halfChecked } = checkedKeys;
      checked.concat(halfChecked).map(key => {
        const isMenu = menuIds.indexOf(key.toString()) >= 0;
        if (isMenu) menu.push(key);
        else res.push(key);
      });
      delete formData.useful;
      if (action === "Edit") formData.id = editId;
      formData.menu = menu.toString();
      formData.res = res.toString();
      saveLoadingSet(true);
      const func = action === "Add" ? API.roleAdd : API.roleEdit;
      func(formData).then(() => {
        saveLoadingSet(false);
        visibleSet(false);
        getData();
      }).catch(() => saveLoadingSet(false));
    });
  };

  const remove = (e: any, id: number) => {
    e.preventDefault();
    API.roleRemove(id).then(getData);
  };

  const onCheck = (checked: any, halfChecked: any) => {
    checkedKeysSet({ checked, halfChecked });
    formRef.validateFields();
  };

  const validator = () => {
    const { checked, halfChecked } = checkedKeys;
    if (!checked.length && !halfChecked.length)
      return Promise.reject("请选择可用功能");

    return Promise.resolve();
  };

  return (
    <>
      <Spin size="large" spinning={loading}>
        <div style={{ padding: "32px 0 0 40px", height: "calc(100vh - 56px)" }}>
          <Access accessible={ac.canUse("add")}>
            <Tag
              icon={<PlusOutlined />}
              color="#1890ff"
              style={{ borderStyle: "dashed", cursor: "default" }}
              onClick={() => {
                formRef.resetFields();
                actionSet("Add");
                editIdSet(0);
                checkedKeysSet({ checked: [], halfChecked: [] });
                visibleSet(true);
              }}
            >
              新增角色
            </Tag>
          </Access>
          {data.map(({ id, name, res }) => (
            <Tag
              key={id}
              closable={ac.canUse("remove")}
              style={{ cursor: "default" }}
              onClose={e => remove(e, id)}
              onClick={() => {
                if (!ac.canUse("edit")) return;

                formRef.setFieldsValue({ name });
                actionSet("Edit");
                editIdSet(id);
                const checked = res.split(",").map(item => parseInt(item));
                checkedKeysSet({ checked, halfChecked: [] });
                visibleSet(true);
              }}
            >
              {name}
            </Tag>
          ))}
        </div>
      </Spin>

      <Drawer
        title={action === "Add" ? "新增角色" : "编辑角色"}
        width={512}
        open={visible}
        onClose={() => visibleSet(false)}
        styles={{
          body: { paddingBottom: 0 },
          footer: { textAlign: "right" },
        }}
        footer={(
          <Space>
            <Button type="primary" loading={saveLoading} onClick={save}>
              保存
            </Button>
            <Button onClick={() => visibleSet(false)}>取消</Button>
          </Space>
        )}
      >
        <Form form={formRef} labelCol={{ flex: "80px" }}>
          <Form.Item label="角色名称" name="name" rules={[{ required: true }]}>
            <Input maxLength={10} />
          </Form.Item>
          <Form.Item
            label="可用功能"
            name="useful"
            rules={[{ required: true, validator }]}
          >
            <Tree
              checkable
              defaultExpandAll
              selectable={false}
              showLine={{ showLeafIcon: false }}
              fieldNames={{ key: "id", title: "name" }}
              treeData={treeData}
              checkedKeys={checkedKeys}
              onCheck={(keys, { halfCheckedKeys }) =>
                onCheck(keys, halfCheckedKeys)}
            />
          </Form.Item>
        </Form>
      </Drawer>
    </>
  );
};
